package com.example.java8.feature_05.method_constructor;

import javax.swing.*;

public class TestMethodRefAndConstructorRef {

	public static void main(String[] args) {
		
		testRefClassMethod();
		testRefObjectInstanceMethod();
		testRefAClassObjectInstanceMethod();
		testRefConstructor();

	}

	/**
	 * 引用类方法
	 * */
	public static void testRefClassMethod(){
		//使用Lambda表达式创建Converter对象
		Converter cvr1 = from -> Integer.valueOf(from);
		/*
		 * 上面Lambda表达式中只有一个形参，因此可以省略圆括号；并且实现代码块只有一条语句
		 * 因此可以省略花括号。由于表达式所实现的convert()方法需要返回值，因此Lambda表达式
		 * 将会把这条代码的值作为返回值。
		 * */
		Integer val = cvr1.convert("99");
		System.out.println("val1" + val);
		/*
		 * 上面Lambda表达式的代码块只有一行调用类方法的代码，因此可以使用如下方法引用进行替换
		 * */
		Converter cvr2 = Integer::valueOf;
		System.out.println("val2" + cvr2.convert("88"));
		/*
		 * 对于上面类方法引用，也就是调用Integer类的valueOf()类方法来实现Converter函数式接口
		 * 中唯一的抽象方法，当调用Converter接口中的唯一的抽象方法时，调用参数将会传给Integer
		 * 类的valueOf()类方法。
		 * */
	}
	
	/**
	 * 引用特定对象的实例方法
	 * */
	public static void testRefObjectInstanceMethod(){
		/*
		 * 使用Lambda表达式创建对象，下面实现代码搜索指定子字符串出现的第一个位置的索引
		 * */
		Converter cvr1  = from -> "deleerhai.com".indexOf(from);
		Integer val1 = cvr1.convert("hai");
		System.out.println("val1" + val1);
		/*
		 * 上面Lambda表达式的代码块只有一行调用"deleerhai.com"的indexOf()实例方法的代码，
		 * 因此可以使用如下方法引用进行替换
		 * */
		Converter cvr2 = "deleerhai.com" :: indexOf;
		System.out.println("val2" + cvr2.convert("hai"));
		/*
		 * 上面的实例方法引用，也就是调用"deleerhai.com"对象的indexOf()实例方法来实现
		 * Converter函数式接口中唯一的抽象方法，当调用Converter接口中唯一的抽象方法时，
		 * 调用参数将会传给"deleerhai.com"对象的indexOf()实例方法。
		 * */
	}
	
	/**
	 * 引用某类对象的实例方法
	 * */
	public static void testRefAClassObjectInstanceMethod(){
		/*
		 * 使用Lambda表达式创建对象，第一个参数将作为调用者
		 * */
		ImDeleerhai id = (a, b, c) -> a.substring(b, c);
		/*
		 * 上面Lambda表达式的代码块只有一条语句，因此程序可以省略花括号；而且由于表达式
		 * 所实现的test()方法需要返回值，因此Lambda表达式将会把这条代码的值作为返回值。
		 * */
		String str1 = id.test("Oh! My Gad! 你TM居然是一个傻B!", 2, 5);
		System.out.println("str1:" + str1);
		/*
		 * 上面Lambda表达式的代码块只有一行a.substring()语句，因此可以使用如下方法
		 * 引用进行替换
		 * */
		ImDeleerhai id2 = String :: substring;
		String str2 = id2.test("Oh! My Gad! 你TM居然是一个傻B!", 2, 5);
		System.out.println("str2:" + str2);
		/*
		 * 对于上面的实例方法引用，也就是调用某个String对象的substring()实例方法来实现
		 * ImDeleerhai函数式接口中唯一的抽象方法，当调用ImDeleerhai接口中唯一的抽象
		 * 方法时，第一个调用参数将作为substring()方法的调用者，剩下的调用参数会作为
		 * substring()实例方法的调用参数。
		 * */
	}
	
	/**
	 * 引用构造器
	 * */
	public static void testRefConstructor(){
		/*
		 * 使用Lambda表达式创建对象
		 * */
		YourSB ysb1 = (String title) -> new JFrame(title);
		/*
		 * 上面Lambda表达式的代码块只有一条语句，因此程序可以省略花括号；而且由于表达式
		 * 所实现的win()方法需要返回值，因此Lambda表达式将会把这条代码的值作为返回值。
		 * */
		JFrame jf1 = ysb1.win("我的窗户");
		System.out.println(jf1);
		/*
		 * 上面代码调用ysb对象的win()方法是————由于yt对象时Lambda表达式创建的，因此win()
		 * 方法执行体就是Lambda表达式的代码块部分，即执行体就是执行new JFrame(title)语句，
		 * 并将这条语句的值作为方法返回值。由于上面Lambda表达式代码块只有一行new JFrame()
		 * 语句，因此可以使用如下构造器引用进行替换。
		 * */
		YourSB ysb2 = JFrame :: new;
		System.out.println(ysb2.win("我的窗户"));
		/*
		 * 对于上面的构造器引用，也就是调用某个JFrame类的构造器来实现YourSB函数式接口中唯一
		 * 的抽象方法，当调用YourSB接口中唯一的抽象方法时，调用参数将会传给JFrame构造器。
		 * 从上面程序中可以看出，调用YourSB对象的win()抽象方法时，实际只传入了一个String
		 * 类型的参数，这个String类型的参数会被传给JFrame构造器————这就确定了是调用JFrame
		 * 类的带一个String参数的构造器。
		 * */
	} 
}
















